﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Sort
{
    delegate void Sort(int[] arr, int beg, int end);

    struct SortData
    {
        public Sort sort;
        public string flag;
    }

    class Program
    {
        const int MAX = 9999;
        static void Main(string[] args)
        {
            //int[] arr2 = new int[] { 100, 30, 90, 20, 41, 61, 51, 2, 1, 52, 61, 102 };
            //lib.PutArr<int>(arr2);
            //RadixSort.sort(arr2);
            //lib.PutArr<int>(arr2);
            //return;
            bool b = false;
            if (b)
            {
                //int[] arr1 = new int[] { 222, 1, 5, 8, 7, 9, 52, 6, 4, 67 };
                //MergeSort.Sort(arr1, 0, 9);
                //lib.PutArr<int>(arr1);
                Check(RadixSort.Sort);
            }
            else 
            {
                SortData[] arr = new SortData[] { 
                                    new SortData { sort = QSort.Sort3,          flag = "QSort.Sort3" } ,
                                    new SortData { sort = BubbleSort.Sort,      flag = "BubbleSort.Sort" } ,
                                    new SortData { sort = SelectSort.Sort,      flag = "SelectSort.Sort" } ,
                                    new SortData { sort = InsertSort.Sort,      flag = "InsertSort.Sort" } ,
                                    new SortData { sort = HeapSort.Sort,        flag = "HeapSort.Sort" } ,
                                    new SortData { sort = HeapSort.heapSort,    flag = "HeapSort.heapSort" } ,
                                    new SortData { sort = MergeSort.Sort,       flag = "MergeSort.Sort" } ,
                                    new SortData { sort = InsertSort.SellSort,  flag = "InsertSort.SellSort" } ,
                                    new SortData { sort = RadixSort.Sort,       flag = "RadixSort.Sort" } ,
                             };
                Check(arr);
            }
        }

        static void Check(SortData[] funs)
        {
            

            Random random = new Random();

            int[] arr = new int[MAX];
            for(int i = 0; i < MAX; i++)
                arr[i] = random.Next(1, 5000);

            foreach(var v in funs)
            {
                DateTime beforDT = System.DateTime.Now;
                int[] copy = (int[])arr.Clone();
                v.sort(copy, 0, MAX - 1);
                DateTime afterDT = System.DateTime.Now;
                TimeSpan ts = afterDT.Subtract(beforDT);
                Console.WriteLine("{0,-25}总共花费：{1}ms.", v.flag, ts.TotalMilliseconds);

                int temp = 0;
                for (int i = 0; i < MAX; i++)
                {
                    if (temp <= copy[i])
                    {
                        temp = copy[i];
                    }
                    else
                    {
                        (v.flag + " error.\n").print();
                        break;
                    }
                }
            }
        }

        static int GetRandomSeed()
        {

            byte[] bytes = new byte[4];

            System.Security.Cryptography.RNGCryptoServiceProvider r = new System.Security.Cryptography.RNGCryptoServiceProvider();

            r.GetBytes(bytes);

            return BitConverter.ToInt32(bytes, 0);

        }

        static void Check(Sort sort, string prefix = "")
        {
            const int RANGE = 30;
            int[] arr = new int[RANGE];
            int[] arrClone;
            int idx = 0;
            while (true)
            {
                idx++;
                if (idx > 9999)
                    break;

                for (int i = 0; i < RANGE; i++)
                {
                    //(DateTime.Now.Ticks + idx + i).print("\n");
                    Random random = new Random(GetRandomSeed());
                    arr[i] = random.Next(1, RANGE);
                    arrClone = (int[])arr.Clone();
                }

                sort(arr, 0, RANGE-1);
                //lib.PutArr<int>(arr);
                //Console.WriteLine("");

                int temp = 0;
                for (int i = 0; i < RANGE; i++)
                {
                    if (temp <= arr[i])
                    {
                        temp = arr[i];
                    }
                    else
                    {
                        (" error.\n").print();
                    }
                }
            }
        }
    }
}
